package com.winit.project.web;

import com.alibaba.fastjson.JSONObject;
import com.winit.common.base.beans.LoginUser;
import com.winit.common.base.web.BaseController;
import com.winit.common.filter.UserInfoUtil;
import com.winit.common.util.ZipUtil;
import com.winit.project.core.branch.Project;
import com.winit.project.core.edition.PackageEdition;
import com.winit.project.service.ProjectService;
import com.winit.project.task.DrawSqlTask;
import com.winit.project.task.DrawSqlTaskContainer;
import com.winit.project.util.ProjectUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/projectREST")
public class ProjectRESTController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(ProjectRESTController.class);

    @Autowired
    private ProjectService projectService;

    /**
     * 自动抽取工程sql文件
     *
     * @param request
     * @return
     */
    @RequestMapping("/autoDrawSql")
    @ResponseBody
    public Map<String, Object> autoDrawSql(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("com.winit.project.web.ProjectRESTController.autoDrawSql开始");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("com.winit.project.web.ProjectRESTController.autoDrawSql,获取用户信息为空");
            return this.noUserRtn();
        }

        String dir = request.getParameter("dir");
        String integrationId = request.getParameter("integrationId");
        String list = request.getParameter("list");

        Assert.hasText(dir, "com.winit.project.web.ProjectRESTController.autoDrawSql,dir为空");
        Assert.hasText(list, "com.winit.project.web.ProjectRESTController.autoDrawSql,integrationId为空");
        Assert.hasText(list, "com.winit.project.web.ProjectRESTController.autoDrawSql,list为空");

        DrawSqlTask task = new DrawSqlTask(dir, integrationId, list);
        DrawSqlTaskContainer taskContainer = DrawSqlTaskContainer.getInstance();
        try {
            taskContainer.addTask(task);
        } catch (Exception e) {
            rtnMap.put("code", "1");
            rtnMap.put("desc", e.getMessage());
            return this.getRtnMap(rtnMap, userInfo, new JSONObject());
        }
        rtnMap.put("code", "0");
        return this.getRtnMap(rtnMap, userInfo, new JSONObject());
    }

    /**
     * 获取工程代码内sql文件列表
     *
     * @param request
     * @return
     */
    @RequestMapping("/getProjectSqlList")
    @ResponseBody
    public Map<String, Object> getProjectSqlList(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("com.winit.project.web.ProjectRESTController.getProjectSqlList");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("com.winit.project.web.ProjectRESTController.getProjectSqlList,获取用户信息为空");
            return this.noUserRtn();
        }
        String projectName = request.getParameter("projectName");

        Assert.hasText(projectName, "com.winit.project.web.ProjectRESTController.getProjectSqlList,projectName为空");

        JSONObject jsonObject = new JSONObject();

        List<JSONObject> list = new ArrayList<>();
        try {
            Project project = new Project(projectName, true);
            project.drawProjectSql(list);
            rtnMap.put("code", "0");
            jsonObject.put("list", list);
        } catch (Exception e) {
            logger.error("com.winit.project.web.ProjectRESTController.getProjectSqlList 异常", e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "获取sql文件列表异常." + e.getMessage());
        }

        return this.getRtnMap(rtnMap, userInfo, jsonObject);
    }

    /**
     * 获取工程代码内config文件key value值
     *
     * @param request
     * @return
     */
    @RequestMapping("/getProjectConfigList")
    @ResponseBody
    public Map<String, Object> getProjectConfigList(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("com.winit.project.web.ProjectRESTController.getProjectConfigList");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("com.winit.project.web.ProjectRESTController.getProjectConfigList,获取用户信息为空");
            return this.noUserRtn();
        }
        String projectName = request.getParameter("projectName");

        Assert.hasText(projectName, "com.winit.project.web.ProjectRESTController.getProjectConfigList,projectName为空");

        JSONObject jsonObject = new JSONObject();

        try {
            Project project = new Project(projectName, true);
            List<JSONObject> list = project.getConfigKeyAndValueForPro();
            rtnMap.put("code", "0");
            jsonObject.put("list", list);
        } catch (Exception e) {
            logger.error("com.winit.project.web.ProjectRESTController.getProjectConfigList 异常", e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "获取配置列表异常." + e.getMessage());
        }

        return this.getRtnMap(rtnMap, userInfo, jsonObject);
    }

    /**
     * 下载工程sql文件
     *
     * @param request
     * @param response
     */
    @RequestMapping("/downloadProjectSql")
    @ResponseBody
    public void downloadProjectSql(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.info("com.winit.project.web.ProjectRESTController.downloadProjectSql开始");

        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("com.winit.project.web.ProjectRESTController.downloadProjectSql 原因:后台尝试获取用户信息对象,但得到的是空对象");
            return;
        }

        String filePath = request.getParameter("filePath");
        String fileName = request.getParameter("fileName");
        Assert.hasText(fileName, "com.winit.project.web.ProjectRESTController.downloadProjectSql, 文件名为空");
        Assert.hasText(filePath, "com.winit.project.web.ProjectRESTController.downloadProjectSql, 文件路径为空");

        response.setCharacterEncoding("utf-8");
        response.setContentType("multipart/form-data");
        response.setHeader("Content-Disposition", "attachment;fileName=" + new String(fileName.getBytes("utf-8"), "iso-8859-1"));

        InputStream inputStream = null;
        OutputStream os = null;
        try {
            inputStream = new FileInputStream(new File(filePath));
            os = response.getOutputStream();
            byte[] b = new byte[2048];
            int length;
            while ((length = inputStream.read(b)) > 0) {
                os.write(b, 0, length);
            }
        } catch (FileNotFoundException e) {
            logger.error("com.winit.project.web.ProjectRESTController.downloadProjectSql目标文件找不到. fileName="
                    + fileName + ",filePath=" + filePath, e);
        } catch (IOException e) {
            logger.error("com.winit.project.web.ProjectRESTController.downloadProjectSql IOException. fileName="
                    + fileName + ",filePath=" + filePath, e);
        } finally {
            try {
                os.close();
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取工程测试通过版本号，并判断版本是否存在
     *
     * @param request
     * @return
     */
    @RequestMapping("/getProTestPassVersion")
    @ResponseBody
    public Map<String, Object> getProTestPassVersion(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("com.winit.project.web.ProjectRESTController.getProTestPassVersion");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("com.winit.project.web.ProjectRESTController.getProTestPassVersion,获取用户信息为空");
            return this.noUserRtn();
        }

        String trunkName = request.getParameter("trunkName");

        Assert.hasText(trunkName, "com.winit.project.web.ProjectRESTController.getProTestPassVersion,trunkName为空");

        JSONObject jsonObject = new JSONObject();

        try {
            jsonObject = projectService.getPassProjectAndEdition(trunkName);
            if (StringUtils.isEmpty(jsonObject.getString("projectName")) || StringUtils.isEmpty(jsonObject.getString("editionNum"))) {
                logger.info("com.winit.project.web.ProjectRESTController.getProTestPassVersion 为空.trunkName=" + trunkName);
                rtnMap.put("code", "1");
                rtnMap.put("desc", "获取工程测试通过版本为空");
            } else {
                jsonObject.put("isEditionExist", projectService.isEditionExist(jsonObject.getString("projectName"), jsonObject.getString("editionNum")));
                rtnMap.put("code", "0");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("com.winit.project.web.ProjectRESTController.getProTestPassVersion 异常.trunkName=" + trunkName, e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "获取工程测试通过版本异常,e:" + e.getMessage());
        }
        return this.getRtnMap(rtnMap, userInfo, jsonObject);
    }

    /**
     * 将工程版本备份代码上传到svn主干
     *
     * @param request
     * @return
     */
    @RequestMapping("/cpCodeToTrunk")
    @ResponseBody
    public Map<String, Object> cpCodeToTrunk(HttpServletRequest request) {
        Map<String, Object> rtnMap = new HashMap<>();
        logger.info("com.winit.project.web.ProjectRESTController.cpCodeToTrunk");
        LoginUser userInfo = UserInfoUtil.getUserInfo(request);
        if (userInfo == null) {
            logger.info("com.winit.project.web.ProjectRESTController.cpCodeToTrunk,获取用户信息为空");
            return this.noUserRtn();
        }

        String projectName = request.getParameter("projectName");
        String editionNum = request.getParameter("editionNum");
        String trunkUrl = request.getParameter("trunkUrl");
        String desc = request.getParameter("desc");

        Assert.hasText(projectName, "com.winit.project.web.ProjectRESTController.cpCodeToTrunk,projectName为空");
        Assert.hasText(editionNum, "com.winit.project.web.ProjectRESTController.cpCodeToTrunk,editionNum为空");
        Assert.hasText(trunkUrl, "com.winit.project.web.ProjectRESTController.cpCodeToTrunk,trunkUrl为空");
        Assert.hasText(desc, "com.winit.project.web.ProjectRESTController.cpCodeToTrunk,desc为空");

        try {
            PackageEdition edition = new PackageEdition(projectName, editionNum, true);
            desc = new String(desc.getBytes("ISO8859-1"), "UTF-8").replace("\n","\r");
            JSONObject jsonObject = edition.cpCodeToTrunk(trunkUrl,desc);
            if (jsonObject.getBoolean("status")) {
                rtnMap.put("code", "0");
            } else {
                rtnMap.put("code", "1");
                rtnMap.put("desc", jsonObject.getString("msg"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("com.winit.project.web.ProjectRESTController.cpCodeToTrunk 异常.projectName=" + projectName + ",editionNum=" + editionNum, e);
            rtnMap.put("code", "1");
            rtnMap.put("desc", "将工程版本备份代码上传到svn主干异常,e:" + e.getMessage());
        }
        return this.getRtnMap(rtnMap, userInfo, new JSONObject());
    }
}
